package aiyh.utils;

import aiyh.utils.annotation.DateFormatAn;
import aiyh.utils.entity.*;
import aiyh.utils.fileUtil.ProperUtil;
import aiyh.utils.mapUtil.UtilHashMap;
import aiyh.utils.mapUtil.UtilLinkedHashMap;
import aiyh.utils.recordset.RecordsetUtil;
import aiyh.utils.service.UtilService;
import aiyh.utils.sqlUtil.builderSql.impl.BuilderSqlImpl;
import aiyh.utils.sqlUtil.whereUtil.Where;
import aiyh.utils.sqlUtil.whereUtil.impl.PrepWhereImpl;
import aiyh.utils.sqlUtil.whereUtil.impl.WhereImpl;
import aiyh.utils.zwl.common.ToolUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ibm.icu.text.SimpleDateFormat;
import org.h2.util.StringUtils;
import weaver.common.util.string.StringUtil;
import weaver.conn.RecordSet;
import weaver.general.GCONST;
import weaver.hrm.HrmUserVarify;
import weaver.hrm.User;
import weaver.systeminfo.SystemEnv;
import weaver.workflow.workflow.WorkflowVersion;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;

/**
 * @author EBU7-dev1-ayh
 * @date 2021/8/23 0023 11:42
 * mybatisTest.dao 工具类
 */


public class Util extends weaver.general.Util {

    static ToolUtil toolUtil = new ToolUtil();
    private static final UtilService utilService = new UtilService();
    private static final RecordSet rs = new RecordSet();
    private static RecordsetUtil recordsetUtil = new RecordsetUtil();;


    /**
     * 获取指定格式的当前时间
     *
     * @param format 格式化字符串
     * @return 指定格式日期的字符串
     */
    public static String getTime(String format) {
        Date date = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(date);
    }

    /**
     * 创建一个SQL where条件，不推荐使用
     *
     * @return Where对象
     */
    @Deprecated
    public static Where createWhereImpl() {
        return new WhereImpl();
    }

    /**
     * 创建一个SQL where条件
     *
     * @return Where对象
     */
    public static Where createPrepWhereImpl() {
        return new PrepWhereImpl();
    }

    /**
     * 创建一个Map工具，可以自定义一些功能，比如链式添加键值对，自定义过滤条件等
     *
     * @return UtilHashMap对象
     */
    public static UtilHashMap<String, Object> createUtilHashMap() {
        return new UtilHashMap<>();
    }

    /**
     * 创建一个SQL构建工具类，通过构建工具可以实现SQL的构建
     *
     * @return BuilderSqlImpl对象
     */
    public static BuilderSqlImpl createSqlBuilder() {
        return new BuilderSqlImpl();
    }

    /**
     * 创建一个Map工具，可以自定义一些功能，比如链式添加键值对，自定义过滤条件等
     *
     * @return UtilLinkedHashMap对象
     */
    public static UtilLinkedHashMap<String, Object> createUtilLinkedHashMap() {
        return new UtilLinkedHashMap<>();
    }

    /**
     * 判断map是否为空或者是否没有数据
     *
     * @param map 判断的map对象
     * @return 是否为空或者和大小为0
     */
    public static boolean mapIsNullOrEmpty(Map map) {
        return Objects.isNull(map) || map.size() == 0;
    }

    /**
     * 去除前后的英文逗号
     *
     * @param sqlBuilder 构建的SQL StringBuilder对象
     * @return 处理后的SQL字符串
     */
    public static String removeSeparator(StringBuilder sqlBuilder) {
        String str = sqlBuilder.toString().trim();
        String removeSeparator = ",";
        if (str.endsWith(removeSeparator)) {
//			如果以分割号结尾，则去除分割号
            str = str.substring(0, str.length() - 1);
        }
        if (str.trim().startsWith(removeSeparator)) {
            str = str.substring(1);
        }
        return str;
    }

    /**
     * 移除前后的指定字符
     * @param sqlBuilder 需要移除的字符串的StringBuilder 对象
     * @param removeSeparator 移除的字符串
     * @return 移除前后指定字符后的字符串
     */
    public static String removeSeparator(StringBuilder sqlBuilder, String removeSeparator) {
        String str = sqlBuilder.toString().trim();
        if (str.endsWith(removeSeparator)) {
//			如果以分割号结尾，则去除分割号
            str = str.substring(0, str.length() - 1);
        }
        if (str.trim().startsWith(removeSeparator)) {
            str = str.substring(1);
        }
        return str;
    }

    /**
     * 移除前后的指定字符
     * @param string 需要移除的字符串的
     * @param removeSeparator 移除的字符串
     * @return 移除前后指定字符后的字符串
     */
    public static String removeSeparator(String string, String removeSeparator) {
        StringBuilder sqlBuilder = new StringBuilder(string);
        String str = sqlBuilder.toString().trim();
        if (str.endsWith(removeSeparator)) {
//			如果以分割号结尾，则去除分割号
            str = str.substring(0, str.length() - 1);
        }
        if (str.trim().startsWith(removeSeparator)) {
            str = str.substring(1);
        }
        return str;
    }

    /**
     * 通过RecordSet对象，获取查询后的值，返回map
     *
     * @param rs         执行查询语句后的RecordSet对象
     * @param conversion 是否大小写转驼峰命名
     * @return 封装后的Map的值
     */
    private static Map<String, Object> getMapMapping(RecordSet rs, boolean conversion) {
        Map<String, Object> map = new HashMap<>();
        String[] columnType = rs.getColumnTypeName();
        int colCounts = 0;
        colCounts = rs.getColCounts() == 0 ? columnType.length : rs.getColCounts();
        toolUtil.writeErrorLog(Arrays.toString(columnType));
        toolUtil.writeErrorLog("字段数：" + colCounts);
        for (int i = 1; i <= colCounts; i++) {
            String key = null;
            String type = "varchar";
            if (columnType != null) {
                if (columnType.length != colCounts) {
                    type = "varchar";
                } else {
                    type = columnType[i - 1];
                }
            }
            if (conversion) {
                key = toCamelCase(rs.getColumnName(i));
            } else {
                key = rs.getColumnName(i);
            }
            rs.getColumnName(i);
            if ("int".equalsIgnoreCase(type) || "Integer".equalsIgnoreCase(type)
                    || "Long".equalsIgnoreCase(type) || "BIGINT".equalsIgnoreCase(type)
                    || "NUMBER".equalsIgnoreCase(type) || "INTEGER".equalsIgnoreCase(type)
                    || "TINYINT".equalsIgnoreCase(type) || "SMALLINT".equalsIgnoreCase(type)) {
                map.put(key, rs.getInt(i) == -1 ? rs.getString(i) : rs.getInt(i));
                continue;
            }
            if ("FLOAT".equalsIgnoreCase(type)) {
                map.put(key, rs.getFloat(i));
                continue;
            }
            if ("DATE".equalsIgnoreCase(type) || "TIMESTAMP".equalsIgnoreCase(type)
                    || "DATETIME".equalsIgnoreCase(type)) {
                map.put(key, rs.getDouble(i));
                continue;
            }
            if ("DOUBLE".equalsIgnoreCase(type)) {
                map.put(key, rs.getDouble(i));
                continue;
            }
            if ("DECIMAL".equalsIgnoreCase(type) || "NUMERIC".equalsIgnoreCase(type)) {
                map.put(key, rs.getDouble(i));
                continue;
            }
            map.put(key, rs.getString(i));
        }
        return map;
    }

    /**
     * 通过RecordSet对象获取map结果
     *
     * @param rs RecordSet对象
     * @return 查询结果map
     */
    public static Map<String, Object> recordSet2Map(RecordSet rs) {
        if (rs.next()) {
            return getMapMapping(rs, false);
        }
        return null;
    }

    /***
     * 通过RecordSet对象获取查询后的map结果
     * @param rs RecordSet对象
     * @param conversion 是否下划线转驼峰命名
     * @return 查询结果map对象
     */
    public static Map<String, Object> recordSet2Map(RecordSet rs, boolean conversion) {
        if (rs.next()) {
            return getMapMapping(rs, conversion);
        }
        return null;
    }

    /**
     * 通过RecordSet对象获取map结果
     *
     * @param rs RecordSet对象
     * @return 查询结果map集合
     */
    public static List<Map<String, Object>> recordSet2MapList(RecordSet rs) {
        List<Map<String, Object>> list = new ArrayList<>();
        while (rs.next()) {
            list.add(getMapMapping(rs, false));
        }
        return list;
    }

    /***
     * 通过RecordSet对象获取查询后的map结果
     * @param rs RecordSet对象
     * @param conversion 是否下划线转驼峰命名
     * @return 查询结果map集合
     */
    public static List<Map<String, Object>> recordSet2MapList(RecordSet rs, boolean conversion) {
        List<Map<String, Object>> list = new ArrayList<>();
        while (rs.next()) {
            list.add(getMapMapping(rs, conversion));
        }
        return list;
    }


    /**
     * 获取查询SQL的映射实体
     *
     * @param rs          查询结果 RecordSet类
     * @param t           反射获取的对象
     * @param emptyFields 对象的字段
     * @param <T>         返回一个赋值后的对象
     * @return 处理后的对象
     * @throws IllegalAccessException IllegalAccessException异常
     */
    private static <T> T getMappingEntity(RecordSet rs, T t, List<Field> emptyFields) throws IllegalAccessException {
        for (Field field : emptyFields) {
            String fieldName = field.getName();
            field.setAccessible(true);
            if (field.getType().equals(String.class)) {
                field.set(t, rs.getString(fieldName));
                continue;
            }
            if (field.getType().equals(Integer.class) || field.getType().equals(int.class)
                    || field.getType().equals(short.class) || field.getType().equals(long.class)
                    || field.getType().equals(Long.class)) {
                field.set(t, rs.getInt(fieldName));
                continue;
            }
            if (field.getType().equals(boolean.class) || field.getType().equals(Boolean.class)) {
                field.set(t, rs.getBoolean(fieldName));
                continue;
            }
            if (field.getType().equals(Float.class) || field.getType().equals(float.class)) {
                field.set(t, rs.getFloat(fieldName));
                continue;
            }
            if (field.getType().equals(Double.class) || field.getType().equals(double.class)) {
                field.set(t, rs.getDouble(fieldName));
                continue;
            }
            if (field.getType().equals(Date.class)) {
                if (field.isAnnotationPresent(DateFormatAn.class)) {
                    DateFormatAn annotation = field.getAnnotation(DateFormatAn.class);
                    String value = annotation.value();
                    try {
                        field.set(t, new SimpleDateFormat(value).parse(rs.getString(fieldName)));
                    } catch (ParseException e) {
                        e.printStackTrace();
                        field.set(t, null);
                    }
                } else {
                    try {
                        field.set(t, rs.getDate(fieldName));
                    } catch (Exception e) {
                        field.set(t, null);
                    }
                }
                continue;
            }
            if (field.getType().equals(BigDecimal.class)) {
                field.set(t, rs.getDouble(fieldName));
            }
        }
        return t;
    }


    /**
     * 获取查询SQL的映射实体
     *
     * @param rs          查询结果 RecordSet类
     * @param t           反射获取的对象
     * @param emptyFields 对象的字段
     * @param conversion  是否下划线转驼峰
     * @param <T>         返回一个赋值后的对象
     * @return 处理后的对象
     * @throws IllegalAccessException IllegalAccessException 异常
     */
    private static <T> T getMappingEntity(RecordSet rs, T t, List<Field> emptyFields, boolean conversion) throws IllegalAccessException {
        if (!conversion) {
            return getMappingEntity(rs, t, emptyFields);
        }
        for (Field field : emptyFields) {
            String fieldName = toUnderlineCase(field.getName());
            field.setAccessible(true);
            if (field.getType().equals(String.class)) {
                field.set(t, rs.getString(fieldName));
                continue;
            }
            if (field.getType().equals(Integer.class) || field.getType().equals(int.class)
                    || field.getType().equals(short.class) || field.getType().equals(long.class)
                    || field.getType().equals(Long.class)) {
                field.set(t, rs.getInt(fieldName));
                continue;
            }
            if (field.getType().equals(boolean.class) || field.getType().equals(Boolean.class)) {
                field.set(t, rs.getBoolean(fieldName));
                continue;
            }
            if (field.getType().equals(Float.class) || field.getType().equals(float.class)) {
                field.set(t, rs.getFloat(fieldName));
                continue;
            }
            if (field.getType().equals(Double.class) || field.getType().equals(double.class)) {
                field.set(t, rs.getDouble(fieldName));
                continue;
            }
            if (field.getType().equals(Date.class)) {
                if (field.isAnnotationPresent(DateFormatAn.class)) {
                    DateFormatAn annotation = field.getAnnotation(DateFormatAn.class);
                    String value = annotation.value();
                    try {
                        field.set(t, new SimpleDateFormat(value).parse(rs.getString(fieldName)));
                    } catch (ParseException e) {
                        e.printStackTrace();
                        field.set(t, null);
                    }
                } else {
                    try {
                        field.set(t, rs.getDate(fieldName));
                    } catch (Exception e) {
                        field.set(t, null);
                    }
                }
                continue;
            }
            if (field.getType().equals(BigDecimal.class)) {
                field.set(t, rs.getDouble(fieldName));
            }
        }
        return t;
    }

    @Deprecated
    public static <T> T recordeSet2Empty(RecordSet rs, Class<T> clazz, boolean conversion) {
        return recordeSet2Entity(rs, clazz, conversion);
    }

    /**
     * 通过查询结果获取到一个映射对象
     *
     * @param rs         查询结果
     * @param clazz      需要映射的类
     * @param conversion 是否下划线转驼峰
     * @param <T>        泛型
     * @return 转换后的对象
     */
    public static <T> T recordeSet2Entity(RecordSet rs, Class<T> clazz, boolean conversion) {
        if (clazz == null) {
            return null;
        }
        try {
            if (rs.next()) {
                T t = clazz.newInstance();
                List<Field> entityFields = getEmptyFields(clazz);
                if (entityFields == null) {
                    toolUtil.writeErrorLog("emptyFields is empty!");
                    return null;
                }
                return getMappingEntity(rs, t, entityFields, conversion);
            }
        } catch (InstantiationException | IllegalAccessException e) {
            toolUtil.writeErrorLog("err" + "\n" + e);
            return null;
        }
        return null;
    }


    @Deprecated
    public static <T> T recordeSet2Empty(RecordSet rs, Class<T> clazz) {
        return recordeSet2Entity(rs, clazz);
    }

    /**
     * 通过查询结果获取到一个映射对象
     *
     * @param rs    查询结果
     * @param clazz 需要映射的类
     * @param <T>   返回改类的实例对象
     * @return 处理后的实体类
     */
    public static <T> T recordeSet2Entity(RecordSet rs, Class<T> clazz) {
        if (clazz == null) {
            return null;
        }
        if (clazz.equals(String.class)) {
            if (rs.next()) {
                return (T) rs.getString(1);
            }
            return null;
        } else if (clazz.equals(Integer.class)) {
            if (rs.next()) {
                return (T) Integer.valueOf(rs.getInt(1));
            }
            return null;
        } else if (clazz.equals(Double.class)) {
            if (rs.next()) {
                return (T) Double.valueOf(rs.getDouble(1));
            }
            return null;
        } else if (clazz.equals(Float.class)) {
            if (rs.next()) {
                return (T) Float.valueOf(rs.getFloat(1));
            }
            return null;
        } else if (clazz.equals(Boolean.class)) {
            if (rs.next()) {
                return (T) Boolean.valueOf(rs.getBoolean(1));
            }
            return null;
        }
        try {
            if (rs.next()) {
                T t = clazz.newInstance();
                List<Field> emptyFields = getEmptyFields(clazz);
                if (emptyFields == null) {
                    return null;
                }
                return getMappingEntity(rs, t, emptyFields);
            }
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
            return null;
        }
        return null;
    }


    /**
     * 获取数据库映射的集合
     *
     * @param rs         查询对象
     * @param clazz      需要映射的类
     * @param conversion 是否下划线转驼峰
     * @param <T>        返回映射实体类集合
     * @return 处理后的实体类集合
     */
    public static <T> List<T> recordeSet2Array(RecordSet rs, Class<T> clazz, boolean conversion) {
        if (clazz == null) {
            return null;
        }
        List<T> list = new ArrayList<>();
        List<Field> entityFields = getEmptyFields(clazz);
        if (entityFields == null) {
            return null;
        }
        while (rs.next()) {
            try {
                T t = clazz.newInstance();
                list.add(getMappingEntity(rs, t, entityFields, conversion));
            } catch (InstantiationException | IllegalAccessException e) {
                e.printStackTrace();
                return null;
            }
        }
        return list;
    }

    /**
     * 获取数据库映射的集合
     *
     * @param rs    查询对象
     * @param clazz 需要映射的类
     * @param <T>   返回映射实体类集合
     * @return 转换后的实体类集合
     */
    public static <T> List<T> recordeSet2Array(RecordSet rs, Class<T> clazz) {
        if (clazz == null) {
            return null;
        }
        List<T> list = new ArrayList<>();
        List<Field> emptyFields = getEmptyFields(clazz);
        if (emptyFields == null) {
            return null;
        }
        while (rs.next()) {
            try {
                if (clazz.equals(String.class)) {
                    list.add((T) rs.getString(1));
                } else if (clazz.equals(Integer.class)) {
                    list.add((T) Integer.valueOf(rs.getInt(1)));
                } else if (clazz.equals(Double.class)) {
                    list.add((T) Double.valueOf(rs.getDouble(1)));
                } else if (clazz.equals(Float.class)) {
                    list.add((T) Float.valueOf(rs.getFloat(1)));
                } else if (clazz.equals(Boolean.class)) {
                    list.add((T) Boolean.valueOf(rs.getBoolean(1)));
                } else {
                    T t = clazz.newInstance();
                    list.add(getMappingEntity(rs, t, emptyFields));
                }
            } catch (InstantiationException | IllegalAccessException e) {
                e.printStackTrace();
                return null;
            }
        }
        return list;
    }


    /**
     * 下划线转驼峰
     *
     * @param underlineStr 带有下划线的字符串
     * @return 驼峰字符串
     */
    public static String toCamelCase(String underlineStr) {
        if (underlineStr == null) {
            return null;
        }
        // 分成数组
        char[] charArray = underlineStr.toCharArray();
        // 判断上次循环的字符是否是"_"
        boolean underlineBefore = false;
        StringBuilder buffer = new StringBuilder();
        for (int i = 0, l = charArray.length; i < l; i++) {
            // 判断当前字符是否是"_",如果跳出本次循环
            if (charArray[i] == 95) {
                underlineBefore = true;
            } else if (underlineBefore) {
                // 如果为true，代表上次的字符是"_",当前字符需要转成大写
                buffer.append(charArray[i] -= 32);
                underlineBefore = false;
            } else {
                // 不是"_"后的字符就直接追加
                buffer.append(charArray[i]);
            }
        }
        return buffer.toString();
    }

    /**
     * 驼峰转 下划线
     *
     * @param camelCaseStr 驼峰字符串
     * @return 带下滑线的String
     */
    public static String toUnderlineCase(String camelCaseStr) {
        if (camelCaseStr == null) {
            return null;
        }
        // 将驼峰字符串转换成数组
        char[] charArray = camelCaseStr.toCharArray();
        StringBuilder buffer = new StringBuilder();
        //处理字符串
        for (int i = 0, l = charArray.length; i < l; i++) {
            if (charArray[i] >= 65 && charArray[i] <= 90) {
                if(i==0){
                    buffer.append(charArray[i] += 32);
                    continue;
                }
                buffer.append("_").append(charArray[i] += 32);
            } else {
                buffer.append(charArray[i]);
            }
        }
        return buffer.toString();
    }

    /**
     * 根据类获取到对应的字段，包括父类的字段
     *
     * @param clazz 需要获取字段的类
     * @return java字段信息
     */
    public static List<Field> getEntityFields(Class<?> clazz) {
        Class<?> temClass = clazz;
        List<Field> fieldList = new ArrayList<>();
        while (temClass != null && temClass != Object.class) {
            fieldList.addAll(Arrays.asList(temClass.getDeclaredFields()));
            temClass = temClass.getSuperclass();
        }
        if (fieldList.size() == 0) {
            return null;
        }
        return fieldList;
    }


    public static List<Field> getEmptyFields(Class<?> clazz) {
        return getEntityFields(clazz);
    }

    /**
     * 根据查询语句生成java文件
     *
     * @param query       查询语句
     * @param javaName    文件名
     * @param packageName 包名
     * @throws IOException io异常
     */
    private static void createJavaFile(String query, String javaName, String packageName) throws IOException {
        RecordSet rs = new RecordSet();
        rs.executeQuery(query);
        List<String> list = new ArrayList<>();
        int colCounts = rs.getColCounts() == 0 ? rs.getColumnTypeName().length : rs.getColCounts();
        for (int i = 1; i <= colCounts; i++) {
            list.add(rs.getColumnName(i));
        }
        String[] columnType = rs.getColumnTypeName();
        StringBuilder content = new StringBuilder();
        StringBuilder importBuilder = new StringBuilder();
        StringBuilder getBuilder = new StringBuilder();
        StringBuilder setBuilder = new StringBuilder();
        StringBuilder toStringBuilder = new StringBuilder("\n\t@Override\n");
        String packageStr = "\npackage " + packageName + "; \n\n";
        content.append("\npublic class ");
        String className = Util.toCamelCase(javaName);
        char[] chars = className.toCharArray();
        if (!Character.isUpperCase(chars[0])) {
            chars[0] -= 32;
        }
        className = String.valueOf(chars) + "PO";
        toStringBuilder.append("\tpublic String toString() {\n\t\treturn \"")
                .append(className)
                .append("{\" +\n");
        content.append(className).append(" {\n\n");
        for (int i = 0; i < list.size(); i++) {
            content.append(getClassField(columnType[i], list.get(i), importBuilder, getBuilder, setBuilder, toStringBuilder));
        }
        toStringBuilder.append("\t\t\t\t'}';\n\t}");
        content.append(setBuilder)
                .append(getBuilder)
                .append(toStringBuilder.toString().replace("{\" +\n\t\t\t\t\", ", "{\" +\n\t\t\t\t\""))
                .append("\n}");
        String contentStr = packageStr + importBuilder + content;
        String path = GCONST.getRootPath().replace(File.separator + "web" + File.separator,
                File.separator + "src" + File.separator) + packageName.replace(".", File.separator) + File.separator + className + ".java";
        System.out.println(path);
        File file = new File(URLDecoder.decode(path, "utf-8"));
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        if (!file.exists()) {
            file.createNewFile();
        } else {
            try {
                System.out.println("已存在文件：" + packageName + "." + className + ".java");
                System.out.print("你想如何处理该文件：替换[r/R]  重命名[w/W]  跳过[n/N] ? ");
                Scanner scanner = new Scanner(System.in);
                String next = scanner.next();
                System.out.println(next);
                if ("w".equalsIgnoreCase(next)) {
                    System.out.print("请输入新的文件名：");
                    String newName = scanner.next();
                    System.out.println(newName);
                    System.out.println("处理中...");
                    createJavaFile(query, newName, packageName);
                } else if ("n".equalsIgnoreCase(next)) {
                    System.out.println("跳过文件生成！");
                    return;
                }
            } catch (Exception e) {
                System.out.println("已存在文件：" + packageName + "." + className + ".java");
            }
        }
        FileOutputStream fos = new FileOutputStream(file);
        byte[] contentInBytes = contentStr.getBytes();
        fos.write(contentInBytes);
        fos.flush();
        fos.close();
        System.out.println("完成");
    }

    /**
     * 根据表名生成java文件
     *
     * @param tableName   表名
     * @param packageName 包名
     * @throws IOException io异常
     */
    public static void creatJavaFileByTable(String tableName, String packageName) throws IOException {
        RecordSet recordSet = new RecordSet();
        String dbType = recordSet.getDBType();
        String query;
        System.out.println(dbType);
        if ("mysql".equalsIgnoreCase(dbType)) {
            query = "select * from " + tableName + " limit 1";
        } else if ("sqlserver".equalsIgnoreCase(dbType)) {
            query = "select TOP 1 * from " + tableName;
        } else {
            query = "select TOP 1 * from " + tableName;
        }
        createJavaFile(query, tableName, packageName);
    }

    /**
     * 根据查询语句生成java问阿金
     *
     * @param sql         查询语句
     * @param fileName    java文件名
     * @param packageName 包名
     * @throws IOException io 异常
     */
    public static void creatJavaFileBySql(String sql, String fileName, String packageName) throws IOException {
        RecordSet recordSet = new RecordSet();
        String dbType = recordSet.getDBType();
        String query;
        System.out.println(dbType);
        if ("mysql".equalsIgnoreCase(dbType)) {
            query = "select * from (" + sql + ") as temp limit 1";
        } else if ("sqlserver".equalsIgnoreCase(dbType)) {
            query = "select TOP 1 * from (" + sql + ") as temp";
        } else {
            query = "select TOP 1 * from (" + sql + ") as temp";
        }
        createJavaFile(query, fileName, packageName);
    }

    /**
     * java字段和数据库字段映射
     *
     * @param type            数据库字段类型
     * @param name            数据库字段名
     * @param importBuilder   导包的构建
     * @param getBuilder      getter方法的构建
     * @param setBuilder      setter方法的构建
     * @param toStringBuilder toString方法的构建
     * @return java字段
     */
    public static String getClassField(String type, String name, StringBuilder importBuilder,
                                       StringBuilder getBuilder, StringBuilder setBuilder, StringBuilder toStringBuilder) {
        if ("TINYINT".equalsIgnoreCase(type)) {
            getBuilder.append("\n\tpublic boolean is")
                    .append(getFirstCase(toCamelCase(name)))
                    .append("(){\n")
                    .append("\t\treturn this.")
                    .append(toCamelCase(name))
                    .append(";\n\t}\n");
            setBuilder.append("\n\tpublic void set")
                    .append(getFirstCase(toCamelCase(name)))
                    .append("(boolean ")
                    .append(toCamelCase(name))
                    .append("){\n")
                    .append("\t\tthis.")
                    .append(toCamelCase(name))
                    .append(" = ")
                    .append(toCamelCase(name))
                    .append(";\n\t}\n");
            toStringBuilder.append("\t\t\t\t\", ")
                    .append(toCamelCase(name))
                    .append("='\" + ")
                    .append(toCamelCase(name))
                    .append(" + '\\'' +\n");
            return "\tprivate boolean " + toCamelCase(name) + ";\n";
        }
        if ("int".equalsIgnoreCase(type) || "SMALLINT".equalsIgnoreCase(type)
                || "MEDIUMINT".equalsIgnoreCase(type) || "NUMBER".equalsIgnoreCase(type)
                || "INTEGER".equalsIgnoreCase(type)) {
            getBuilder.append("\n\tpublic int get")
                    .append(getFirstCase(toCamelCase(name)))
                    .append("(){\n")
                    .append("\t\treturn this.")
                    .append(toCamelCase(name))
                    .append(";\n\t}\n");
            setBuilder.append("\n\tpublic void set")
                    .append(getFirstCase(toCamelCase(name)))
                    .append("(int ")
                    .append(toCamelCase(name))
                    .append("){\n")
                    .append("\t\tthis.")
                    .append(toCamelCase(name))
                    .append(" = ")
                    .append(toCamelCase(name))
                    .append(";\n\t}\n");
            toStringBuilder.append("\t\t\t\t\", ")
                    .append(toCamelCase(name))
                    .append("='\" + ")
                    .append(toCamelCase(name))
                    .append(" + '\\'' +\n");
            return "\tprivate int " + toCamelCase(name) + ";\n";
        }
        if ("BIGINT".equalsIgnoreCase(type)) {
            getBuilder.append("\n\tpublic long get")
                    .append(getFirstCase(toCamelCase(name)))
                    .append("(){\n")
                    .append("\t\treturn this.")
                    .append(toCamelCase(name))
                    .append(";\n\t}\n");
            setBuilder.append("\n\tpublic void set")
                    .append(getFirstCase(toCamelCase(name)))
                    .append("(long ")
                    .append(toCamelCase(name))
                    .append("){\n")
                    .append("\t\tthis.")
                    .append(toCamelCase(name))
                    .append(" = ")
                    .append(toCamelCase(name))
                    .append(";\n\t}\n");
            toStringBuilder.append("\t\t\t\t\", ")
                    .append(toCamelCase(name))
                    .append("='\" + ")
                    .append(toCamelCase(name))
                    .append(" + '\\'' +\n");
            return "\tprivate long " + toCamelCase(name) + ";\n";
        }
        if ("double".equalsIgnoreCase(type) || "BINARY_DOUBLE".equalsIgnoreCase(type)) {
            getBuilder.append("\n\tpublic double get")
                    .append(getFirstCase(toCamelCase(name)))
                    .append("(){\n")
                    .append("\t\treturn this.")
                    .append(toCamelCase(name))
                    .append(";\n\t}\n");
            setBuilder.append("\n\tpublic void set")
                    .append(getFirstCase(toCamelCase(name)))
                    .append("(double ")
                    .append(toCamelCase(name))
                    .append("){\n")
                    .append("\t\tthis.")
                    .append(toCamelCase(name))
                    .append(" = ")
                    .append(toCamelCase(name))
                    .append(";\n\t}\n");
            toStringBuilder.append("\t\t\t\t\", ")
                    .append(toCamelCase(name))
                    .append("='\" + ")
                    .append(toCamelCase(name))
                    .append(" + '\\'' +\n");
            return "\tprivate double " + toCamelCase(name) + ";\n";
        }
        if ("float".equalsIgnoreCase(type) || "BINARY_FLOAT".equalsIgnoreCase(type)) {
            getBuilder.append("\n\tpublic float get")
                    .append(getFirstCase(toCamelCase(name)))
                    .append("(){\n")
                    .append("\t\treturn this.")
                    .append(toCamelCase(name))
                    .append(";\n\t}\n");
            setBuilder.append("\n\tpublic void set")
                    .append(getFirstCase(toCamelCase(name)))
                    .append("(float ")
                    .append(toCamelCase(name))
                    .append("){\n")
                    .append("\t\tthis.")
                    .append(toCamelCase(name))
                    .append(" = ")
                    .append(toCamelCase(name))
                    .append(";\n\t}\n");
            toStringBuilder.append("\t\t\t\t\", ")
                    .append(toCamelCase(name))
                    .append("='\" + ")
                    .append(toCamelCase(name))
                    .append(" + '\\'' +\n");
            return "\tprivate float " + toCamelCase(name) + ";\n";
        }
        if ("DECIMAL".equalsIgnoreCase(type)) {
            getBuilder.append("\n\tpublic BigDecimal get")
                    .append(getFirstCase(toCamelCase(name)))
                    .append("(){\n")
                    .append("\t\treturn this.")
                    .append(toCamelCase(name))
                    .append(";\n\t}\n");
            setBuilder.append("\n\tpublic void set")
                    .append(getFirstCase(toCamelCase(name)))
                    .append("(BigDecimal ")
                    .append(toCamelCase(name))
                    .append("){\n")
                    .append("\t\tthis.")
                    .append(toCamelCase(name))
                    .append(" = ")
                    .append(toCamelCase(name))
                    .append(";\n\t}\n");
            toStringBuilder.append("\t\t\t\t\", ")
                    .append(toCamelCase(name))
                    .append("='\" + ")
                    .append(toCamelCase(name))
                    .append(" + '\\'' +\n");
            importBuilder.append("import java.math.BigDecimal;\n");
            return "\tprivate BigDecimal " + toCamelCase(name) + ";\n";
        }
        if ("DATE".equalsIgnoreCase(type) || "DATETIME".equalsIgnoreCase(type)) {
            getBuilder.append("\n\tpublic Date get")
                    .append(getFirstCase(toCamelCase(name)))
                    .append("(){\n")
                    .append("\t\treturn this.")
                    .append(toCamelCase(name))
                    .append(";\n\t}\n");
            setBuilder.append("\n\tpublic void set")
                    .append(getFirstCase(toCamelCase(name)))
                    .append("(Date ")
                    .append(toCamelCase(name))
                    .append("){\n")
                    .append("\t\tthis.")
                    .append(toCamelCase(name))
                    .append(" = ")
                    .append(toCamelCase(name))
                    .append(";\n\t}\n");
            toStringBuilder.append("\t\t\t\t\", ")
                    .append(toCamelCase(name))
                    .append("='\" + ")
                    .append(toCamelCase(name))
                    .append(" + '\\'' +\n");
            importBuilder.append("import java.util.Date;\n");
            return "\tprivate Date" + toCamelCase(name) + ";\n";
        }
        if ("char".equalsIgnoreCase(type) || "VARCHAR".equalsIgnoreCase(type) || "TEXT".equalsIgnoreCase(type)) {
            getBuilder.append("\n\tpublic String get")
                    .append(getFirstCase(toCamelCase(name)))
                    .append("(){\n")
                    .append("\t\treturn this.")
                    .append(toCamelCase(name))
                    .append(";\n\t}\n");
            setBuilder.append("\n\tpublic void set")
                    .append(getFirstCase(toCamelCase(name)))
                    .append("(String ")
                    .append(toCamelCase(name))
                    .append("){\n")
                    .append("\t\tthis.")
                    .append(toCamelCase(name))
                    .append(" = ")
                    .append(toCamelCase(name))
                    .append(";\n\t}\n");
            toStringBuilder.append("\t\t\t\t\", ")
                    .append(toCamelCase(name))
                    .append("='\" + ")
                    .append(toCamelCase(name))
                    .append(" + '\\'' +\n");
            return "\tprivate String " + toCamelCase(name) + ";\n";
        }
        return "";
    }

    /**
     * 首字母转大写
     *
     * @param str 需要转换的字符串
     * @return 首字母转为大写后的字符串
     */
    public static String getFirstCase(String str) {
        char[] chars = str.toCharArray();
        if (!Character.isUpperCase(chars[0])) {
            chars[0] -= 32;
        }
        return String.valueOf(chars);
    }


    /**
     * 通过文件名获取到对应的配置文件map对象
     *
     * @param fileName prop/prop2map/文件夹下的文件名（不包含.properties）
     * @return 配置文件对应的map对象
     */
    public static Map<String, Object> getProperties2Map(String fileName) {
        String propertyPath = GCONST.getPropertyPath();
        if (StringUtil.isNullOrEmpty(fileName)) {
            return null;
        }
        if (fileName.contains(".properties")) {
            fileName.replace(".properties", "");
        }
        String path = propertyPath + "prop2map" + File.separator + fileName + ".properties";
        Properties prop = new Properties();
        Map<String, Object> map = new HashMap<>();
        InputStream inputStream = null;
        try {
            inputStream = new BufferedInputStream(new FileInputStream(path));
            prop.load(inputStream);
            Enumeration<?> enumeration = prop.propertyNames();
            while (enumeration.hasMoreElements()) {
                String key = String.valueOf(enumeration.nextElement());
                map.put(key, prop.getProperty(key));
            }
        } catch (IOException e) {
            throw new RuntimeException("找不到文件：" + path);
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return map;
    }

    /**
     * 根据配置文件文件名以及前缀获取对应的配置文件信息
     *
     * @param fileName
     * @param prefix
     * @return
     */
    public static Map<String, Object> readProperties2Map(String fileName, String prefix) {
        String propertyPath = GCONST.getPropertyPath();
        if (StringUtil.isNullOrEmpty(fileName)) {
            return null;
        }
        if (fileName.contains(".properties")) {
            fileName.replace(".properties", "");
        }
        String path = propertyPath + "prop2map" + File.separator + fileName + ".properties";
        ProperUtil prop = new ProperUtil();
        Map<String, Object> map = new HashMap<>();
        InputStream inputStream = null;
        try {
            inputStream = new BufferedInputStream(new FileInputStream(path));
            prop.load(inputStream);
//			Enumeration<?> enumeration = prop.propertyNames();
//			顺序读取
            Enumeration<?> enumeration = prop.keys();
            while (enumeration.hasMoreElements()) {
                String key = (String) enumeration.nextElement();
                String value = prop.getProperty(key);
                keyHandler(prefix, key, value, map);
            }
        } catch (IOException e) {
            throw new RuntimeException("找不到文件：" + path);
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return map;
    }


    /**
     * 处理配置文件的key和value映射关系
     *
     * @param prePrefix 前缀
     * @param key       key
     * @param value     value
     * @param preResult 结果对象
     * @return
     */
    public static Map<String, Object> keyHandler(String prePrefix, String key, Object value, Map<String, Object> preResult) {
        String objRegex = "^(" + prePrefix + "\\.)(?<key>(\\w+))$";
        Pattern compile = Pattern.compile(objRegex);
        Matcher matcher = compile.matcher(key);
        if (matcher.find()) {
//			只匹配前缀.key=value模式的
            String resultKey = matcher.group("key");
            preResult.put(resultKey, prop2MapPutValue(value));
        }
        String moreKey = "^(" + prePrefix + "\\.)(?<key>(?<objKey>(\\w+))\\.(\\S)+(?!\\[))";
        compile = Pattern.compile(moreKey);
        matcher = compile.matcher(key);
        if (matcher.find()) {
//			匹配前缀.key1.key2=value模式的
            String objKey = matcher.group("objKey");
            String prefixStr = prePrefix + "." + objKey;
            Map<String, Object> valueMap;
            if (preResult.containsKey(objKey)) {
                valueMap = (Map<String, Object>) preResult.get(objKey);
                keyHandler(prefixStr, key, value, valueMap);
                return null;
            }
            valueMap = new HashMap<>();
            keyHandler(prefixStr, key, value, valueMap);
            preResult.put(objKey, valueMap);
            return null;
        }
        String strList = "^(" + prePrefix + "\\.)(?<key>(\\w+))(\\[(?<index>([0-9])+)])$";
        compile = Pattern.compile(strList);
        matcher = compile.matcher(key);
        if (matcher.find()) {
//			匹配前缀.key[0]=value模式的
            String objKey = matcher.group("key");
            int index = Integer.parseInt(matcher.group("index"));
            if (preResult.containsKey(objKey)) {
//				存在值
                List<Object> valueList = (List<Object>) preResult.get(objKey);
                if (index >= valueList.size()) {
                    valueList.add(prop2MapPutValue(value));
                } else {
                    valueList.set(index, prop2MapPutValue(value));
                }
                return null;
            }
            List<Object> valueList = new ArrayList<>();
            valueList.add(prop2MapPutValue(value));
            preResult.put(objKey, valueList);
            return null;
        }
        String objArray = "^(" + prePrefix + "\\.)(?<arrKey>(\\w+))(\\[(?<index>([0-9])+)])\\.(?<objKey>(\\S)+)$";
//		String objArray = "^("+prePrefix+"\\.)(?<arrKey>(\\w+))(\\[(?<index>([0-9])+)])(\\.(?<objKey>(\\S)+))+";
        compile = Pattern.compile(objArray);
        matcher = compile.matcher(key);
        if (matcher.find()) {
//			匹配前缀.key[0].name=value的模式
            String arrKey = matcher.group("arrKey");
            String objKey = matcher.group("objKey");
            int index = Integer.parseInt(matcher.group("index"));
            List<Map<String, Object>> mapList;
            if (preResult.containsKey(arrKey)) {
//				存在
                mapList = (List<Map<String, Object>>) preResult.get(arrKey);
//				mapList
                Map<String, Object> valueMap;
                if (index >= mapList.size()) {
                    valueMap = new HashMap<>();
                    valueMap.put(objKey, prop2MapPutValue(value));
                    mapList.add(valueMap);
                    return null;
                }
                valueMap = mapList.get(index);
                String arrMoreKey = "(?<key>(\\w+))\\.(\\S)+(?!\\[)";
                Pattern arrMoreKeyCompile = Pattern.compile(arrMoreKey);
                Matcher arrMoreKeyMatcher = arrMoreKeyCompile.matcher(objKey);
                if (arrMoreKeyMatcher.find()) {
                    String arrMoreObjKey = arrMoreKeyMatcher.group("key");
                    Map<String, Object> arrMoreValue;
                    if (valueMap.containsKey(arrMoreObjKey)) {
                        arrMoreValue = (Map<String, Object>) valueMap.get(arrMoreObjKey);
                        keyHandler(arrMoreObjKey, objKey, value, arrMoreValue);
                        return null;
                    }
                    arrMoreValue = new HashMap<>();
                    keyHandler(arrMoreObjKey, objKey, value, arrMoreValue);
                    valueMap.put(arrMoreObjKey, arrMoreValue);
                    return null;
                }
                arrMoreKey = "(?<key>(\\w+))(\\[(?<index>([0-9])+)])$";
                arrMoreKeyCompile = Pattern.compile(arrMoreKey);
                arrMoreKeyMatcher = arrMoreKeyCompile.matcher(objKey);
                if (arrMoreKeyMatcher.find()) {
                    String arrMoreArrKey = arrMoreKeyMatcher.group("key");
                    int arrMoreIndex = Integer.parseInt(arrMoreKeyMatcher.group("index"));
                    List<Object> arrMoreListValue;
                    if (valueMap.containsKey(arrMoreArrKey)) {
//						存在值
                        arrMoreListValue = (List<Object>) valueMap.get(arrMoreArrKey);
                        if (arrMoreIndex >= arrMoreListValue.size()) {
                            arrMoreListValue.add(prop2MapPutValue(value));
                        } else {
                            arrMoreListValue.set(arrMoreIndex, prop2MapPutValue(value));
                        }
                        return null;
                    }
                    arrMoreListValue = new ArrayList<>();
                    arrMoreListValue.add(prop2MapPutValue(value));
                    valueMap.put(arrMoreArrKey, arrMoreListValue);
                    return null;
                }

//				直接添加
                valueMap.put(objKey, prop2MapPutValue(value));
                return null;
            }
//			不存在
            mapList = new ArrayList<>();
            Map<String, Object> valueMap = new HashMap<>();
            valueMap.put(objKey, prop2MapPutValue(value));
            mapList.add(valueMap);
            preResult.put(arrKey, mapList);
        }
        return null;
    }

    public static Object prop2MapPutValue(Object value) {
        if (value == null) {
            return null;
        }
        String valueStr = String.valueOf(value).trim();
        if (valueStr.startsWith("\"") && valueStr.endsWith("\"")) {
            return valueStr.substring(1, valueStr.length() - 1);
        }
        if (valueStr.contains(",")) {
            if (valueStr.contains("\\,")) {
                String[] split = valueStr.split("(?<!\\\\),");
                for (int i = 0; i < split.length; i++) {
                    split[i] = split[i].replaceAll("\\\\,", ",");
                }
                return split;
            }
            return valueStr.split(",");
        }
        return value;
    }

    /**
     * 通过文件名获取到对应的配置文件map对象
     *
     * @param fileName prop/prop2map/文件夹下的文件名（不包含.properties）
     * @param prefix   配置文件中配置项的前缀
     * @return 配置文件指定前缀对应的map对象
     */
    @Deprecated
    public static Map<String, Object> getProperties2Map(String fileName, String prefix) {
        String propertyPath = GCONST.getPropertyPath();
        if (StringUtil.isNullOrEmpty(fileName)) {
            return null;
        }
        if (fileName.contains(".properties")) {
            fileName.replace(".properties", "");
        }
        String path = propertyPath + "prop2map" + File.separator + fileName + ".properties";
        Properties prop = new Properties();
        Map<String, Object> map = new HashMap<>();
        InputStream inputStream = null;
        try {
            inputStream = new BufferedInputStream(new FileInputStream(path));
            prop.load(inputStream);
            Enumeration<?> enumeration = prop.propertyNames();
            while (enumeration.hasMoreElements()) {
                String key = (String) enumeration.nextElement();
                if (key.contains(prefix + ".")) {
                    map.put(key.replace(prefix + ".", ""), prop.getProperty(key));
                }
            }
        } catch (IOException e) {
            throw new RuntimeException("找不到文件：" + path);
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return map;
    }

    public static Map<String, List<String>> parsingSq2Map(String sql) {
        Map<String, List<String>> map = new HashMap<>();
        String pattern = "\\{{2}(?<table>((?!\\$)\\s\\S)+?)\\.(?<field>\\s\\S+?)}{2}";
        Pattern compile = Pattern.compile(pattern);
        Matcher matcher = compile.matcher(sql);
        while (matcher.find()) {
            if (map.containsKey(matcher.group("table"))) {
                map.get(matcher.group("table")).add(matcher.group("field"));
            } else {
                map.put(matcher.group("table"), new ArrayList<String>() {{
                    add(matcher.group("field"));
                }});
            }
        }
        return map;
    }

    public static Matcher parsingSql2Matcher(String sql) {
        String pattern = "\\{{2}(?<table>((?!\\$)\\s\\S)+?)\\.(?<field>\\s\\S+?)}{2}";
        Pattern compile = Pattern.compile(pattern);
        return compile.matcher(sql);
    }

    public static String parsingSqlByRequestAndWorkflowId(String sql, String requestId, String workflowId) {
        String requestIdPattern = "\\{{2}(\\$requestId)?}{2}";
        String workflowIdIdPattern = "\\{{2}(\\$workflowId)?}{2}";
        String result = sql.replaceAll(requestIdPattern, StringUtil.isNullOrEmpty(requestId) ? "''" : requestId);
        result = result.replaceAll(workflowIdIdPattern, StringUtil.isNullOrEmpty(workflowId) ? "''" : workflowId);
        return result;
    }

    public static String parsingSq(String sql, Map<String, Object> params) {
        String result = sql;
        String requestIdPattern = "\\{{2}(\\$requestId)?}{2}";
        String workflowIdIdPattern = "\\{{2}(\\$workflowId)?}{2}";
        result = result.replaceAll(requestIdPattern, ObjectUtil.isNull(params.get("requestId")) ? "''" : "'" + params.get("requestId") + "'");
        result = result.replaceAll(workflowIdIdPattern, ObjectUtil.isNull(params.get("workflowId")) ? "''" : "'" + params.get("workflowId") + "'");
        for (Map.Entry<String, Object> param : params.entrySet()) {
            String pattern_ = "#\\{{2}(" + param.getKey() + ")?}{2}";
            result = result.replaceAll(pattern_, ObjectUtil.isNull(param.getValue()) ? "''" : String.valueOf(param.getValue()));
            String pattern = "\\{{2}(" + param.getKey() + ")?}{2}";
            result = result.replaceAll(pattern, ObjectUtil.isNull(param.getValue()) ? "''" : "'" + param.getValue() + "'");
        }
        return result;
    }

    //	去重
    public static <T> List<T> deWeight(List<T> list, Function<? super T, ?> keyExtractor) {
        return list.stream().filter(distinctByKey(keyExtractor)).collect(Collectors.toList());
    }

    //
    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
//		putIfAbsent添加不存在的键，返回null，如果为null表示不重复
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }


    public static Map<String, Object> object2Map(Object obj) {
        if (obj == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<>();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                if (key.compareToIgnoreCase("class") == 0) {
                    continue;
                }
                Method getter = property.getReadMethod();
                Object value = getter != null ? getter.invoke(obj) : null;
                map.put(key, value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }


    public static String getWorkflowNameById(String workflowid) {
        RecordSet rs = new RecordSet();
        String sql = "select workflowname from workflow_base where id = ?";
        rs.executeQuery(sql, workflowid);
        if (rs.next()) {
            return rs.getString("workflowname");
        }
        return "";
    }

    public static Object getRequestTitleById(String requestid) {
        RecordSet rs = new RecordSet();
        String sql = "select requestnamenew from workflow_requestbase where requestid = ?";
        rs.executeQuery(sql, requestid);
        if (rs.next()) {
            return rs.getString("requestnamenew");
        }
        return "";
    }


    public static ApiConfigMainDTO queryApiConfig(String id) {
        ApiConfigMainDTO apiConfigMain = utilService.getApiConfigMain(id);
//		System.out.println(JSON.toJSONString(apiConfigMain));
        return apiConfigMain;
    }

    public static ApiConfigMainDTO queryApiConfigTree(String id) {
        ApiConfigMainDTO apiConfigMain = utilService.getApiConfigMainTree(id);
//		System.out.println(JSON.toJSONString(apiConfigMain));
        return apiConfigMain;
    }

    public static <T> AZipOutputStream createZip(List<T> inputList) throws IOException {
        return createZip(inputList, File.separator);
    }

    private static <T> AZipOutputStream createZip(List<T> inputList, String base) throws IOException {
        FileOutputStream fileOutputStream = null;

        try {
            File file = new File(AZipOutputStream.filePath);
            if (!file.exists()) {
                //先得到文件的上级目录，并创建上级目录，在创建文件
                file.getParentFile().mkdirs();
                try {
                    //创建文件
                    file.createNewFile();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
            fileOutputStream = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        if (fileOutputStream == null) {
            return null;
        }
        AZipOutputStream zipOut = new AZipOutputStream(fileOutputStream);
        int catchLen = 10 * 1024;
        for (int i = 0; i < inputList.size(); i++) {
            T item = inputList.get(i);
            if (item instanceof InputStream) {
//				属于单级文件，直接压缩并返回
                try {
                    zipOut.putNextEntry(new ZipEntry(base + i));
                } catch (IOException e) {
                    throw new IOException(e.toString());
                }
                byte[] buffer = new byte[catchLen];
                int len = 0;
                while ((len = ((InputStream) item).read(buffer)) != -1) {
                    zipOut.write(buffer, 0, len);
                }
                zipOut.closeEntry();
            }
            if (item instanceof AInputStream) {
                try {
                    zipOut.putNextEntry(new ZipEntry(((AInputStream) item).getFileName()));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                byte[] buffer = new byte[catchLen];
                int len = 0;
                while ((len = ((AInputStream) item).getInputStream().read(buffer)) != -1) {
                    try {
                        zipOut.write(buffer, 0, len);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                zipOut.closeEntry();
            }
            if (item instanceof ListZipEntity) {
                ListZipEntity listZipEntity = (ListZipEntity) item;
                if (listZipEntity.isDirectory()) {
//					表示属于文件夹，循环添加处理文件夹
                    handlerDirectory(listZipEntity.getFileList(), zipOut, base + listZipEntity.getDirectory() + File.separator);
                } else {
                    List<AInputStream> aInputStreams = listZipEntity.getaInputStreamList();
                    for (AInputStream aInputStream : aInputStreams) {
                        try {
                            zipOut.putNextEntry(new ZipEntry(aInputStream.getFileName()));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        byte[] buffer = new byte[catchLen];
                        int len = 0;
                        while ((len = (aInputStream.getInputStream()).read(buffer)) != -1) {
                            try {
                                zipOut.write(buffer, 0, len);
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                        zipOut.closeEntry();
                    }
                }
            }
        }
        return zipOut;
    }

    private static void handlerDirectory(List<ListZipEntity> fileList, AZipOutputStream zipOut, String base) throws IOException {
        int catchLen = 10 * 1024;
        for (ListZipEntity listZipEntity : fileList) {
            if (listZipEntity.isDirectory()) {
//			    如果是文件夹
                handlerDirectory(listZipEntity.getFileList(), zipOut, base + listZipEntity.getDirectory() + File.separator);
            } else {
                List<AInputStream> aInputStreams = listZipEntity.getaInputStreamList();
                for (AInputStream aInputStream : aInputStreams) {
                    try {
                        zipOut.putNextEntry(new ZipEntry(aInputStream.getFileName()));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    byte[] buffer = new byte[catchLen];
                    int len = 0;
                    while ((len = (aInputStream.getInputStream()).read(buffer)) != -1) {
                        try {
                            zipOut.write(buffer, 0, len);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    zipOut.closeEntry();
                }
            }
        }
    }

    public static Map<String, String> queryLanguage(int groupId, int languageId) {
        return utilService.queryLanguage(groupId, languageId);
    }

    public static Map<String, String> queryLanguage(int groupId, HttpServletRequest request, HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        int languageId = user.getLanguage();
        return utilService.queryLanguage(groupId, languageId);
    }


    public static String getHtmlLabelName(int id, int languageId, String defaultStr) {
        String htmlLabelName = SystemEnv.getHtmlLabelName(id, languageId);
        return htmlLabelName == null ? defaultStr : htmlLabelName;
    }

    public static String getHtmlLabelName(int id, int languageId) {
        return SystemEnv.getHtmlLabelName(id, languageId);
    }

    public static String getHtmlLabelName(LabelHtmlIndex labelHtmlIndex, User user) {
        return Util.getHtmlLabelName(labelHtmlIndex.getLabelIndex(),
                user.getLanguage(), labelHtmlIndex.getDefaultStr());
    }


    /**
     * 获取流程主表
     *
     * @param workflowId
     * @return
     */
    public static String getMainTable(String workflowId) {
        String versionStringByWfid = WorkflowVersion.getVersionStringByWfid(workflowId);
        String query = "select tablename from workflow_bill " +
                " where id in (select formid from workflow_base " +
                " where id in (" + versionStringByWfid + ") )";
        rs.executeQuery(query);
        rs.next();
        return rs.getString(1);
    }


    /**
     * 根据流程和流程字段查询文档目录
     *
     * @param workflowId
     * @param docField
     * @return
     */
    public static String getDocCategorys(String workflowId, String docField) {
        RecordSet rs = new RecordSet();
        rs.executeQuery("select formid from workflow_base where id = ?", workflowId);
        String formId = Util.recordeSet2Entity(rs, String.class);
        String query = "select doccategory from workflow_fileupload where fieldid = (select id from workflow_billfield where fieldname = ? and billid = ?)";
        rs.executeQuery(query, docField, formId);
        String docCategorys = Util.null2String(Util.recordeSet2Entity(rs, String.class));
        if (StringUtils.isNullOrEmpty(docCategorys)) {
            query = "select doccategory from workflow_base where id = ?";
            rs.executeQuery(query, workflowId);
            rs.next();
            docCategorys = Util.null2String(rs.getString(1));
        }
        if (StringUtils.isNullOrEmpty(docCategorys)) {
            docCategorys = ",,1";
        }
        return docCategorys;
    }

    /**
     * 根据流程和流程字段查询文档目录
     *
     * @param workflowId
     * @param docFieldId
     * @return
     */
    public static String getDocCategorysById(String workflowId, String docFieldId) {
        RecordSet rs = new RecordSet();
//		rs.executeQuery("select formid from workflow_base where id = ?",workflowId);
//		String formId = Util.recordeSet2Entity(rs, String.class);
        String query = "select doccategory from workflow_fileupload where workflowid = ? and fieldid = ?";
        rs.executeQuery(query, workflowId, docFieldId);
        String docCategorys = Util.null2String(Util.recordeSet2Entity(rs, String.class));
        if (StringUtils.isNullOrEmpty(docCategorys)) {
            query = "select doccategory from workflow_base where id = ?";
            rs.executeQuery(query, workflowId);
            rs.next();
            docCategorys = Util.null2String(rs.getString(1));
        }
        if (StringUtils.isNullOrEmpty(docCategorys)) {
            docCategorys = ",,1";
        }
        return docCategorys;
    }

    public static String null2DefaultStr(Object obj, String defaultStr) {
        String objStr = Util.null2String(obj);
        if (StringUtils.isNullOrEmpty(objStr) && StringUtils.isNullOrEmpty(defaultStr)) {
            return "";
        }
        if (StringUtils.isNullOrEmpty(objStr) && !StringUtils.isNullOrEmpty(defaultStr)) {
            return defaultStr;
        }
        return objStr;
    }


    public static <T> T mapToObject(Map<String, Object> map, Class<T> t) throws Exception {
        if (map == null) {
            return null;
        }
        T obj = t.newInstance();
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            int mod = field.getModifiers();
            if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                continue;
            }
            field.setAccessible(true);
            if (field.getType().equals(String.class)) {
                if (map.containsKey(field.getName())) {
                    if (map.get(field.getName()) == null) {
                        field.set(obj, null);
                    } else {
                        field.set(obj, String.valueOf(map.get(field.getName())));
                    }
                }
                continue;
            }
            if (field.getType().equals(Integer.class)) {
                if (map.containsKey(field.getName())) {
                    if (map.get(field.getName()) == null || "".equals(map.get(field.getName()))) {
                        field.set(obj, null);
                    } else {
                        field.set(obj, Integer.valueOf(String.valueOf(map.get(field.getName()))));
                    }
                }
                continue;
            }
            if (field.getType().equals(Boolean.class)) {
                if (map.containsKey(field.getName())) {
                    if (map.get(field.getName()) == null || "".equals(map.get(field.getName()))) {
                        field.set(obj, null);
                    } else {
                        field.set(obj, Boolean.valueOf(String.valueOf(map.get(field.getName()))));
                    }
                }
                continue;
            }
            if (field.getType().equals(Float.class)) {
                if (map.containsKey(field.getName())) {
                    if (map.get(field.getName()) == null || "".equals(map.get(field.getName()))) {
                        field.set(obj, null);
                    } else {
                        field.set(obj, Float.valueOf(String.valueOf(map.get(field.getName()))));
                    }
                }
                continue;
            }
            if (field.getType().equals(Double.class)) {
                if (map.containsKey(field.getName())) {
                    if (map.get(field.getName()) == null || "".equals(map.get(field.getName()))) {
                        field.set(obj, null);
                    } else {
                        field.set(obj, Double.valueOf(String.valueOf(map.get(field.getName()))));
                    }
                }
                continue;
            }
            if (field.getType().equals(int.class)) {
                if (map.containsKey(field.getName())) {
                    if (map.get(field.getName()) == null || "".equals(map.get(field.getName()))) {
                        field.set(obj, null);
                    } else {
                        field.set(obj, Integer.parseInt(String.valueOf(map.get(field.getName()))));
                    }
                }
                continue;
            }
            if (field.getType().equals(float.class)) {
                if (map.containsKey(field.getName())) {
                    if (map.get(field.getName()) == null || "".equals(map.get(field.getName()))) {
                        field.set(obj, null);
                    } else {
                        field.set(obj, Float.parseFloat(String.valueOf(map.get(field.getName()))));
                    }
                }
                continue;
            }
            if (field.getType().equals(double.class)) {
                if (map.containsKey(field.getName())) {
                    if (map.get(field.getName()) == null || "".equals(map.get(field.getName()))) {
                        field.set(obj, null);
                    } else {
                        field.set(obj, Double.parseDouble(String.valueOf(map.get(field.getName()))));
                    }
                }
                continue;
            }
            if (field.getType().equals(boolean.class)) {
                if (map.containsKey(field.getName())) {
                    if (map.get(field.getName()) == null || "".equals(map.get(field.getName()))) {
                        field.set(obj, null);
                    } else {
                        field.set(obj, Boolean.parseBoolean(String.valueOf(map.get(field.getName()))));
                    }
                }
                continue;
            }
        }
        return obj;
    }

    public static <T> T strMapToObject(Map<String, String> map, Class<T> t) throws Exception {
        if (map == null) {
            return null;
        }
        T obj = t.newInstance();
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            int mod = field.getModifiers();
            if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                continue;
            }
            field.setAccessible(true);
            if (map.containsKey(field.getName())) {
                field.set(obj, map.get(field.getName()));
            }
        }
        return obj;
    }

    /**
     * 获取完整的错误信息
     * @param throwable 异常
     * @return 完整堆栈信息
     */
    public static String getErrString(Throwable throwable){
        StringWriter  stringWriter = new StringWriter();
        throwable.printStackTrace(new PrintWriter(stringWriter,true));
        new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                try {
                    stringWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
        return stringWriter.getBuffer().toString();
    }

    /**
     * 获取RecordSetUtil的SQL代理类对象
     * @param t
     * @param <T>
     * @return
     */
    public static <T> T getMapper(Class<T> t) {
        return recordsetUtil.getMapper(t);
    }
}
